﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Jb.Common.Extensions;
using Jb.Domain;
using Jb.Web.ViewModels;
using Jb.Web.Utility;
using AutoMapper;
using Jb.Web.ViewModels.UtilityModels;
using System.Data;

namespace Jb.Web.Areas.Private.Controllers
{
    [Authorize(Roles = "Company Admin,Company User,Admin")]
    public class ContactController : BaseController
    {
		private JbEntities _Context = new JbEntities();
        
		#region Constructors
		public ContactController()
		{
		}

		public ContactController(UserViewModel currentUser)
			: base(currentUser)
        {
        }
		#endregion Constructors

		#region Action Methods

        /// <summary>
        /// Lists Contacts for this company
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult Index(String id = null)
        {
            return View("List", BuildList(id));
        }

        /// <summary>
        /// Lists Contacts for this company
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult List(String id = null)
        {
            return View(BuildList(id));
        }

		/// <summary>
        /// Gets a Contact from Database to edit
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult Edit(int id = 0, String IsSaved = null)
        {
            Contact entity = id == 0 ? new Contact() : _Context.Contacts.Include("Address").FirstOrDefault(P => P.ID == id);
            if (entity.ID == 0)
            {
                entity.CompanyID = LoggedInUser.Contact.CompanyID;
                entity.Gender = "M";
                entity.IsActive = true;
                entity.Address = new Address();
            }
            ContactViewModel viewModel = Mapper.Map<Contact, ContactViewModel>(entity);
            ViewData[AppConstants.ViewDataKeys.SAVED] = IsSaved; 
            return View(viewModel);
        }

		/// <summary>
        /// Saves Contact Information into the Database
        /// </summary>
        /// <param name="viewModel"></param>
        /// <returns></returns>
		[HttpPost]
		public ActionResult Edit(ContactViewModel viewModel)
        {
			if (!ModelState.IsValid)
                return View(viewModel);

            if (viewModel.CompanyID != LoggedInUser.Contact.CompanyID)  //Probable hacking attempt
                return base.RedirectToAccessDenied();

			Contact entity = null; 
			if (viewModel.ID == 0)
            {
                entity = new Contact();
                entity.CreatedOn = DateTime.Now;                
                _Context.AddToContacts(entity);
            }
            else
                entity = _Context.Contacts.Include("Address").FirstOrDefault(P => P.ID == viewModel.ID);

            DateTime addresssCreated = viewModel.ID > 0 ? entity.Address.CreatedOn : DateTime.Now;
            entity = Mapper.Map<ContactViewModel, Contact>(viewModel, entity);

            //FIXME: JoraTali for Automapper. Need to give a better solution with child object property mapping.
            entity.Address.CreatedOn = addresssCreated;
            entity.ModifiedOn = entity.Address.ModifiedOn = DateTime.Now;
            entity.Address.ModifiedBy = LoggedInUser.ID;
		
            _Context.SaveChanges();
            ///Refresh Currently Logged in user's cache
            if (entity.ID == LoggedInUser.Contact.ID)
                SessionCache.CurrentUser.Contact = Mapper.Map<Contact, ContactViewModel>(entity, SessionCache.CurrentUser.Contact);
            String url = String.Format("Edit/{0}", entity.ID);
            return RedirectToAction(url, new { IsSaved = "True" });
        }

        /// <summary>
        /// Creates an User from a Contact information or Saves existing user info
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <param name="contactId"></param>        
        /// <returns>
        /// -1 -> Duplicate user name        
        /// -2 -> Invalid Contact Information
        /// -3 -> Requested User was not found for edit
        /// +1 -> For a successful save operation
        /// </returns>
        [HttpPost]
        public int CreateUserFromContact(String userName, String password, int contactId, int userId)
        {
            if (_Context.IsDuplicateUserName(userName, userId))
                return -1;
            Contact contact = _Context.Contacts.FirstOrDefault(P => P.ID == contactId && P.CompanyID == LoggedInUser.Contact.CompanyID);
            if (contact == null)
                return -2;

            if (userId > 0) ///Edit User
            {
                User user = _Context.Users.FirstOrDefault(P => P.ID == userId && P.ContactID == contactId);
                if (user == null)
                    return -3;
                
                user.UserName = userName;
                user.Password = password;
                //user.GroupID = ConfigReader.UserGroupIDOfCompanyUser;
                //user.IsActive = true;
            }
            else //Add as new User
            {   
                User user = new User();
                user.UserName = userName;
                user.Password = password;
                user.ContactID = contactId;
                user.GroupID = ConfigReader.UserGroupIDOfCompanyUser;
                user.IsActive = true;

                _Context.AddToUsers(user);                
            }
            _Context.SaveChanges();
            return 1;
        }

		#endregion Action Methods
		
		#region Helper Methods

        /// <summary>
        /// Builds a list of contacts
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        private ListConfig BuildList(String id)
        {
            int pageNo = id.ToInt() > 0 ? id.ToInt() : 1;
            UtilityDAO dao = new UtilityDAO();
            Jb.Domain.DbParameter[] parameters = new[]{
                new Jb.Domain.DbParameter("@CompanyID", LoggedInUser.Contact.CompanyID)
            };
            DataSet ds = dao.GetDataSet(DbObject.SP.GET_CONTACTS_BY_COMPANY, parameters, true);
            int totalRecord = ds != null ? ds.Tables[0].Rows.Count : 0;
            PagerConfig pagerConfig = new PagerConfig(pageNo, ConfigReader.PageSize, totalRecord);
            
            ListConfig listConfig = new ListConfig(ds.Tables[0], pagerConfig);
            return listConfig;            
        }

        #endregion			
    }
}


